/*
验证服务器有效性的模块
 */
// 引入sha1
const sha1=require('sha1')
// 引入config模块
const config=require('../config')
// 引入config模块
const {getUserDataAsync,parseXmlAsync,formatMessage}=require('../utils/tool')
//引入 template模块
const template =require('./template')
//引入 reply模块
const reply =require('./reply')
console.log('replay/index')
module.exports= () =>{
    return async (req,res,next)=>{
        console.log(req.method)
        // 微信服务器提交的参数
        // console.log(req.query)
        /*
        { signature: '0631c510ef82306f0302927484aa575ea9b34d62', 微信的加密签名
      echostr: '1094439402354023869',微信的随机字符串
      timestamp: '1568704665', 微信的发送请求时间戳
      nonce: '1641573458' }   微信的随机数字
         */
        const {signature,echostr,timestamp,nonce}=req.query;
        const {token}=config;
        // 1、将参与微信签名的三个参数（timestap nonce  token） 按照字典序排序并组合在一起形成一个数组token是网页上设置的
        const arr=[timestamp,nonce,token];
        const arrSort=arr.sort();
        // console.log(arrSort);
        // 2、将数组里面所有参数拼成一个字符串，进行sha1加密
        const str=arrSort.join('');
        const sha1Str=sha1(str);
        // console.log(sha1Str);
        // console.log(req.query);
        // 3、加密完成就生成了一个signnature。和微信发送过来的进行对比。
        /*
        微信服务器会发送两种类型的消息给开发者服务器
        1、get请求
            -验证服务器的有效性
        2、post请求
            -微信服务器会把用户发送的数据以post的方式转发到开发者服务器上
         */

        if(req.method=='GET'){
            if(sha1Str==signature){
                //如果一致 返回给微信echostr
                res.send(echostr)
            }else{
                //如果不一样
                console.log('reply 不一样，只有用户发送了消息才会有数据')
                res.end()
            }
        }else if(req.method=='POST'){ //这里要精确的判断 因为method有好多种
            // -微信服务器会把用户发送的数据以post的方式转发到开发者服务器上
            // 验证消息来源于微信服务器 post的消息也带着 验证
            /*
               { signature: '0631c510ef82306f0302927484aa575ea9b34d62', 微信的加密签名
             echostr: '1094439402354023869',微信的随机字符串
             timestamp: '1568704665', 微信的发送请求时间戳
             nonce: '1641573458' }   微信的随机数字
                */
            if(sha1Str!=signature){
                res.end('post err')
            }

            // console.log(req.query)
            /*
            { signature: 'f4049a2a9e997c2e764d69c6afe5dca8d6cac6cb',
              timestamp: '1568773108',
              nonce: '1129964022',
              openid: 'ob0GgwpBgCFKmV9RlMaAC_TROkww' }
                用户的openid 每个用户是唯一的
             */

            //接受请求体中的数据，这些数据是流式的
            const xmlData =await getUserDataAsync(req);
            // console.log(xmlData)
            /*
            <xml>
                开发者id
                <ToUserName><![CDATA[gh_d4a95ef75187]]></ToUserName>
                用户的openid
                <FromUserName><![CDATA[ob0GgwpBgCFKmV9RlMaAC_TROkww]]></FromUserName>
                发送的时间戳
                <CreateTime>1568774922</CreateTime>
                发送的消息类型（文本  图片  语音  视频）
                <MsgType><![CDATA[text]]></MsgType>
                发送的内容
                <Content><![CDATA[1212]]></Content>
                消息id  微信服务器会默认保存3天用户发送的数据，通过此id三天内能找到消息数据，三天后会销毁
                <MsgId>22459456381893263</MsgId>
            </xml>
             */
             // 将XML数据 解析 为 json对象
            const jsData = await parseXmlAsync(xmlData)
            // console.log(jsData)
            /*
            { xml:
               { ToUserName: [ 'gh_d4a95ef75187' ],
                 FromUserName: [ 'ob0GgwpBgCFKmV9RlMaAC_TROkww' ],
                 CreateTime: [ '1568775792' ],
                 MsgType: [ 'text' ],
                 Content: [ '12' ],
                 MsgId: [ '22459469009532154' ] } }
             */

            //格式化方法
            const message=formatMessage(jsData);
            // console.log(message)
            /*
            { ToUserName: 'gh_d4a95ef75187',
              FromUserName: 'ob0GgwpBgCFKmV9RlMaAC_TROkww',
              CreateTime: '1568776811',
              MsgType: 'text',
              Content: '333',
              MsgId: '22459485438525990' }
             */

            // 简单的自动回复  都要回复xml类型
            /*
            一旦遇到一下情况，微信会再公众号回话中，向用户发系统提示“’该公众号暂时无法提供服务，请稍后再试‘
                1、开发者在5秒内未回复任何内容
                2、开发者回复了异常数据，比如json数据、字符串、xml数据中有多余的空格 等
             */

            //将reply函数 改装成了  async函数，此时返回值变成了promise对象
            //必须用await才能拿到返回值
            let options=await reply(message)
            // console.log(options)

            //有6中回复类型 看用户是操作的是什么类型 还是事件推送
            let replyMessage=template(options);
            // console.log(replyMessage)
            //  返回响应 给微信服务器
            res.send(replyMessage);


            // 如果开发者服务器 没有返回相应给微信服务器，微信服务器会发送三次请求过来。所以先暂时发送一个 end，等写完后 在真正的调用send
            // res.end('');
        }else{
            res.end('error')
        }
    }
}